/**
 * Copyright (c) [2021-2021] [libbylg@126.com]
 * [lplogger] is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL
 * v2. You may obtain a copy of Mulan PSL v2 at:
 *             http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more
 * details.
 */
#ifndef LP_LOGGER_DEFAULT_H
#define LP_LOGGER_DEFAULT_H

#include "lp_logger.h"

// clang-format off
//  Usage: DEF_LP_LEVEL_DEFAULT(id, name, text, text_len)
#define LP_LEVEL_DEFAULT_TABLE()                        \
    DEF_LP_LEVEL_DEFAULT(0, LP_LEVEL_DEBUG, "DEBUG", 5) \
    DEF_LP_LEVEL_DEFAULT(1, LP_LEVEL_INFOR, "INFOR", 5) \
    DEF_LP_LEVEL_DEFAULT(2, LP_LEVEL_WARNI, "WARNI", 5) \
    DEF_LP_LEVEL_DEFAULT(3, LP_LEVEL_ERROR, "ERROR", 5) \
    /* (end) */

//  Usage: DEF_LP_SINK_ATTR_DEFAULT(id, name, attrstr, cpptype)
#define LP_SINK_ATTR_DEFAULT_TABLE()                                                                                    \
    DEF_LP_SINK_ATTR_DEFAULT(LP_SINK_ATTR_CUSTOM_BEGIN + 0, LP_SINK_ATTR_CONSOLE_COLOR,      "color"   , bool)          \
    DEF_LP_SINK_ATTR_DEFAULT(LP_SINK_ATTR_CUSTOM_BEGIN + 1, LP_SINK_ATTR_LOCALFILE_FILEPATH, "logfile" , const char*)   \
    /* (end) */

//  Usage: DEF_LP_MSGVIEW_DEFAULT(id, name, cpptype)
#define LP_MSGVIEW_DEFAULT_TABLE()                                      \
    DEF_LP_MSGVIEW_DEFAULT(0, LP_MSGVIEW_LEVEL      , int8_t)           \
    DEF_LP_MSGVIEW_DEFAULT(1, LP_MSGVIEW_TIMESTAMP  , struct timeval*)  \
    DEF_LP_MSGVIEW_DEFAULT(2, LP_MSGVIEW_DETIAL     , const char*)      \
    DEF_LP_MSGVIEW_DEFAULT(3, LP_MSGVIEW_DETIAL_LEN , int32_t)          \
    DEF_LP_MSGVIEW_DEFAULT(4, LP_MSGVIEW_TID        , pid_t)            \
    DEF_LP_MSGVIEW_DEFAULT(5, LP_MSGVIEW_MODULE     , int8_t)           \
    /* (end) */

//  Usage: DEF_LP_FORMAT_DEFAULT(keychar, name, tag)
#define LP_FORMAT_DEFAULT_TABLE()                                   \
    DEF_LP_FORMAT_DEFAULT('L', LP_FORMAT_LEVEL      ,   level)      \
    DEF_LP_FORMAT_DEFAULT('l', LP_FORMAT_SHORTLEVEL ,   shortlevel) \
    DEF_LP_FORMAT_DEFAULT('D', LP_FORMAT_DATE       ,   date)       \
    DEF_LP_FORMAT_DEFAULT('H', LP_FORMAT_TIME       ,   time)       \
    DEF_LP_FORMAT_DEFAULT('S', LP_FORMAT_TIMESTAMP  ,   timestamp)  \
    DEF_LP_FORMAT_DEFAULT('X', LP_FORMAT_DETIAL     ,   detial)     \
    DEF_LP_FORMAT_DEFAULT('t', LP_FORMAT_TID        ,   tid)        \
    DEF_LP_FORMAT_DEFAULT('p', LP_FORMAT_PID        ,   pid)        \
    DEF_LP_FORMAT_DEFAULT('m', LP_FORMAT_MODULE     ,   module)     \
    /* (end) */

//  Usage: DEF_LP_SINK_DEFAULT(id, name)
#define LP_SINK_DEFAULT_TABLE()                          \
    DEF_LP_SINK_DEFAULT(0, LP_SINK_CONSOLE, console)     \
    DEF_LP_SINK_DEFAULT(1, LP_SINK_LOCALFILE, localfile) \
/* (end) */

// clang-format on
//! 缺省定义的日志级别
enum lp_level_default {
#define DEF_LP_LEVEL_DEFAULT(id, name, text, text_len) name = id,
    LP_LEVEL_DEFAULT_TABLE()
#undef DEF_LP_LEVEL_DEFAULT

    // ---
    LP_LEVEL_DEFAULT_COUNT
};

//! 缺省自定义的 sink 属性
enum lp_sink_attr_id_default {
#define DEF_LP_SINK_ATTR_DEFAULT(id, name, attrstr, cpptype) name = id,
    LP_SINK_ATTR_DEFAULT_TABLE()
#undef DEF_LP_SINK_ATTR_DEFAULT
};

//! 消息视图的 id 定义
enum lp_msgview_id_default {
#define DEF_LP_MSGVIEW_DEFAULT(id, name, cpptype) name = id,
    LP_MSGVIEW_DEFAULT_TABLE()
#undef DEF_LP_MSGVIEW_DEFAULT

    //--
    LP_MSGVIEW_COUNT_DEFAULT
};

//! 缺省提供的格式化方案
enum lp_format_default {
#define DEF_LP_FORMAT_DEFAULT(keychar, name, tag) name = keychar,
    LP_FORMAT_DEFAULT_TABLE()
#undef DEF_LP_FORMAT_DEFAULT

    //--
    LP_FORMAT_DEFAULT_COUNT
};

enum lp_sink_default {
#define DEF_LP_SINK_DEFAULT(id, name, tag) name = id,
    LP_SINK_DEFAULT_TABLE()
#undef DEF_LP_SINK_DEFAULT

    //--
    LP_SINK_DEFULT_COUNT
};

enum lp_sinkmask_default {
#define DEF_LP_SINK_DEFAULT(id, name, tag) name##_MASK = ((uint64_t)(1) << (name)),
    LP_SINK_DEFAULT_TABLE()
#undef DEF_LP_SINK_DEFAULT
};

//! 一个缺省的日志消息的定义
struct lp_msg_default {
    int8_t level;
    int8_t module_id;
    struct timeval timestamp;
    const char* function;
    const char* filename;
    int32_t filename_len;
    pid_t tid;
    int32_t lineno;
    int32_t detial_len;
    const char* detial;
};

#define LP_PATTERN_ESCAPE_CHAR '%'

// clang-format off
LPEXTERN struct lp_sink_t*          lp_new_sink_console(void* context, LP_ATTR_PROVIDER provider);
LPEXTERN void                       lp_del_sink_console(struct lp_sink_t* sink);

LPEXTERN struct lp_sink_t*          lp_new_sink_localfile(void* context, LP_ATTR_PROVIDER provider);
LPEXTERN void                       lp_del_sink_localfile(struct lp_sink_t* sink);

LPEXTERN struct lp_sink_t*          lp_sink_provider_default(int8_t sink_id);
LPEXTERN struct lp_format_t*        lp_format_provider_default(char keychar);
LPEXTERN struct lp_level_t*         lp_level_provider_default(int8_t level);
LPEXTERN struct lp_module_t*        lp_module_provider_default(int8_t module_id);
LPEXTERN uintptr_t                  lp_msgview_provider_default(void* msg, int8_t msgview_id);

LPEXTERN int32_t                    lp_format_date_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_time_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_timestamp_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_level_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_shortlevel_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_tid_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_pid_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_detial_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_linebreak_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_colorstart_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_colorclear_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);
LPEXTERN int32_t                    lp_format_module_default(struct lp_format_t* format, void* msg, char** ptr, int32_t* len);

LPEXTERN int                        lp_logger_default_init(const char* filepath);
LPEXTERN void                       lp_logger_default_destroy();

// clang-format on

#endif // LP_LOGGER_DEFAULT_H
